package com.bugpool.leilema.tc.util;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.bugpool.leilema.tc.bean.interfaces.TreeFeature;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * @Author wh
 * @Description 树工具类
 * @Date 2023/6/9 8:45
 * @Version 1.0
 **/
public class TreeUtil {
    // todo 第一版   遍历

//    /**
//     * 构建树形结构
//     *
//     * @param trees
//     * @param rootNodeId
//     * @param <V>
//     * @return
//     */
//    public static <V extends TreeFeature<V>> List<V> build(List<V> trees, Long rootNodeId) {
//        if (CollectionUtils.isEmpty(trees)) {
//            return new ArrayList<>();
//        }
//        //根节点
//        List<V> roots = trees.stream()
//                .filter(node -> node.getParentId().equals(rootNodeId))
//                .sorted(Comparator.comparing(V::getOrder))
//                .collect(Collectors.toList());
//        roots.stream().forEach(node -> {
//            node.setChildrenList(getChild(node.getNodeId(), trees));
//        });
//        return roots;
//    }
//
//    public static <V extends TreeFeature<V>> List<V> getChild(Long nodeId, List<V> nodeList) {
//        //子菜单
//        return nodeList.stream()
//                .filter(node -> node.getParentId().equals(nodeId))
//                .map((node) -> {
//            node.setChildrenList(getChild(node.getNodeId(), nodeList));
//            return node;
//        }).collect(Collectors.toList());
//    }

    //todo 第二版
    /**
     * 构建树形结构
     *
     * @param trees
     * @param rootNodeId
     * @param <V>
     * @return
     */
    public static <V extends TreeFeature<V>> List<V> build(List<V> trees, Long rootNodeId) {
        if (CollectionUtils.isEmpty(trees)) {
            return new ArrayList<>();
        }
        //根节点
        List<V> roots = trees.stream().filter(node -> node.getParentId().equals(rootNodeId)).collect(Collectors.toList());
        //其他节点
        List<V> others = trees.stream().filter(node -> node.getParentId() != null).sorted(Comparator.comparing(V::getNodeId)).collect(Collectors.toList());
        return buildTree(roots, others);
    }

    /**
     * 生成树形结构
     *
     * @param roots  根节点
     * @param others 子节点
     * @param <V>
     * @return
     */
    private static <V extends TreeFeature<V>> List<V> buildTree(List<V> roots, List<V> others) {
        if (!CollectionUtils.isEmpty(others)) {
            //声明一个map，用来过滤已操作过的数据
            Map<Long, Long> map = new ConcurrentHashMap<>();
            //节点遍历
            roots.forEach(beanTree -> addChildren(others, beanTree, map));
            return roots;
        }
        return new ArrayList<V>();
    }

    /**
     * 获取子节点列表
     *
     * @param others   所有子节点
     * @param beanTree 根节点
     * @param map      过滤已加入过的节点
     * @param <V>
     */
    private static <V extends TreeFeature<V>> void addChildren(List<V> others, V beanTree, Map<Long, Long> map) {
        List<V> childList = new ArrayList();
        others.stream()
                //判断是否已经被处理过了
                .filter(node -> !map.containsKey(node.getNodeId()))
                //获取当前节点的子节点
                .filter(node -> node.getParentId().equals(beanTree.getNodeId()))
                //子节点下所有的节点,也需要加进去
                .forEach(node -> {
                    map.put(node.getNodeId(), node.getParentId());
                    addChildren(others, node, map);
                    childList.add(node);
                });
        beanTree.setChildrenList(childList);
    }


}
